package go_service

import (
	"bufio"
	"context"
	"fmt"
	"os/exec"
)

// GetServiceLogs 获取服务的日志信息
//
// 参数:
//
//	ctx: 上下文对象，用于控制超时和取消操作
//	lines: 要获取的日志行数，如果lines <= 0则默认返回50行
//
// 返回值:
//
//	string: 日志内容的字符串
//	error: 如果获取成功返回nil，否则返回对应的错误
//
// 示例:
//
//	service := NewService("nginx", "Nginx Web Server", "/usr/sbin/nginx")
//	ctx := context.Background()
//
//	// 获取最近100行日志
//	logs, err := service.GetServiceLogs(ctx, 100)
//	if err != nil {
//	    fmt.Printf("获取日志失败: %v\n", err)
//	    return
//	}
//	fmt.Println("最近日志:")
//	fmt.Println(logs)
func (s *Service) GetServiceLogs(ctx context.Context, lines int) (string, error) {
	if lines <= 0 {
		lines = 50 // 默认显示50行
	}

	cmd := exec.CommandContext(ctx, "journalctl", "-u", s.Name, "-n", fmt.Sprintf("%d", lines), "--no-pager")
	output, err := cmd.CombinedOutput()
	if err != nil {
		return "", fmt.Errorf("failed to get service logs: %w", err)
	}

	return string(output), nil
}

// GetServiceLogsSince 获取从指定时间开始的日志
//
// 参数:
//
//	ctx: 上下文对象，用于控制超时和取消操作
//	since: 时间字符串，格式为"YYYY-MM-DD HH:MM:SS"或相对时间如"1 hour ago"
//
// 返回值:
//
//	string: 从指定时间开始的日志内容
//	error: 如果获取成功返回nil，否则返回对应的错误
//
// 示例:
//
//	service := NewService("nginx", "Nginx Web Server", "/usr/sbin/nginx")
//	ctx := context.Background()
//
//	// 获取从今天开始的日志
//	logs, err := service.GetServiceLogsSince(ctx, "today")
//	if err != nil {
//	    fmt.Printf("获取日志失败: %v\n", err)
//	    return
//	}
//
//	// 获取从1小时前开始的日志
//	logs, err = service.GetServiceLogsSince(ctx, "1 hour ago")
//	if err != nil {
//	    fmt.Printf("获取日志失败: %v\n", err)
//	    return
//	}
//	fmt.Println(logs)
func (s *Service) GetServiceLogsSince(ctx context.Context, since string) (string, error) {
	cmd := exec.CommandContext(ctx, "journalctl", "-u", s.Name, "--since", since, "--no-pager")
	output, err := cmd.CombinedOutput()
	if err != nil {
		return "", fmt.Errorf("failed to get service logs: %w", err)
	}

	return string(output), nil
}

// GetServiceLogsFollow 实时获取服务日志（流式）
//
// 参数:
//
//	ctx: 上下文对象，用于控制超时和取消操作
//
// 返回值:
//
//	<-chan string: 日志行的通道，实时接收新的日志
//	<-chan error: 错误通道，用于接收可能的错误
//
// 示例:
//
//	service := NewService("nginx", "Nginx Web Server", "/usr/sbin/nginx")
//	ctx := context.Background()
//
//	logChan, errChan := service.GetServiceLogsFollow(ctx)
//
//	go func() {
//	    for {
//	        select {
//	        case log := <-logChan:
//	            fmt.Println("新日志:", log)
//	        case err := <-errChan:
//	            fmt.Printf("日志错误: %v\n", err)
//	            return
//	        case <-ctx.Done():
//	            fmt.Println("停止日志监控")
//	            return
//	        }
//	    }
//	}()
func (s *Service) GetServiceLogsFollow(ctx context.Context) (<-chan string, <-chan error) {
	logChan := make(chan string)
	errorChan := make(chan error)

	go func() {
		defer close(logChan)
		defer close(errorChan)

		cmd := exec.CommandContext(ctx, "journalctl", "-u", s.Name, "-f", "--no-pager")
		stdout, err := cmd.StdoutPipe()
		if err != nil {
			errorChan <- fmt.Errorf("failed to create pipe: %w", err)
			return
		}

		if err := cmd.Start(); err != nil {
			errorChan <- fmt.Errorf("failed to start journalctl: %w", err)
			return
		}

		scanner := bufio.NewScanner(stdout)
		for scanner.Scan() {
			logChan <- scanner.Text()
		}

		if err := scanner.Err(); err != nil {
			errorChan <- fmt.Errorf("error reading logs: %w", err)
		}

		cmd.Wait()
	}()

	return logChan, errorChan
}
